<?php

namespace App\Http\Controllers\Ali;

use App\Http\Controllers\Controller;
use DB;
use Log;

class DysmsController extends Controller
{
    private $_sendUrl;
    private $_key;
    private $_secret;

    //获取阿里大于key和secret http://hb.hbjc2018.cn/api/chu/hbjc/alidysmsKeySec

    public function __construct() {
        $alidysmsKeySec = curl('http://39.106.15.202/api/chu/gsby/alidysmsKeySec');
        $alidysmsKeySec = json_decode($alidysmsKeySec);
        $this->_key = $alidysmsKeySec->_key;
        $this->_secret = $alidysmsKeySec->_secret;
        $this->_sendUrl = 'https://dysmsapi.aliyuncs.com/?';
    }

    /**
     * 发送同样内容的短信
     */
    public function SendSms($param) {
        // 1.2. 业务API参数
        $paramData = [
            'Action'        => 'SendSms',       //系统规定参数。取值：SendBatchSms。
            'PhoneNumbers'  => $param['PhoneNumbers'],      //接收短信的手机号
            'SignName'      => $param['SignName'],   //短信签名名称:发送消息的头/前缀，如【汇邦检测】
            'TemplateCode'  => $param['TemplateCode'],   //短信模板ID:SMS_
            'TemplateParam' => json_encode($param['TemplateParam']),   //发送消息的参数
            'OutId'         => config('constant.name_admin').date('YmdHis').rand(1000, 9999),   //外部流水扩展字段
        ];
        return $this->getRes($paramData);
    }

    /**
     * 批量发送短信
     */
    public function SendBatchSms($param) {
        // 1.2. 业务API参数
        $paramData = [
            'Action'            => 'SendBatchSms',       //系统规定参数。取值：SendBatchSms。
            'PhoneNumberJson'   => json_encode($param['PhoneNumbers']),      //接收短信的手机号
            'SignNameJson'      => json_encode($param['SignNames']),   //短信签名名称:发送消息的头/前缀，如【汇邦检测】
            'TemplateParamJson' => json_encode($param['TemplateParams']),   //发送消息的参数
            'TemplateCode'      => $param['TemplateCode'],   //短信模板ID:SMS_
            'OutId'             => config('constant.name_admin').date('YmdHis').rand(1000, 9999),   //外部流水扩展字段
        ];
        return $this->getRes($paramData);
    }

    /**
     * 查看短信发送记录和发送状态
     */
    public function QuerySendDetails($param) {
        // 1.2. 业务API参数
        $paramData = [
            'Action'      => 'QuerySendDetails',       //系统规定参数。取值：QuerySendDetails。
            'CurrentPage' => $param['CurrentPage'],      //分页查看发送记录，指定发送记录的当前页码。
            'PageSize'    => $param['PageSize'],   //分页查看发送记录，指定每页显示的短信记录数量。 取值范围为1~50。
            'PhoneNumber' => $param['PhoneNumber'],   //接收短信的手机号码。
            'SendDate'    => $param['SendDate'],   //短信发送日期，支持查询最近30天的记录。
            'BizId'       => $param['BizId'],   //发送回执ID，即发送流水号。
            'OutId'       => config('constant.name_admin').date('YmdHis').rand(1000, 9999),   //外部流水扩展字段
        ];
        return $this->getRes($paramData);
    }

    /**
     * 申请/修改短信签名
     * AddSmsSign/ModifySmsSign
     */
    public function AddSmsSign($param) {
        // 1.2. 业务API参数
        $paramData = [
            'Action'     => isset($param['Action']) ? $param['Action'] : 'AddSmsSign',       //系统规定参数。取值：SendSms。
            'SignName'   => $param['SignName'],   //短信签名名称:发送消息的头/前缀，如【汇邦检测】
            'SignSource' => 1,   //签名来源。取值：0：企事业单位的全称或简称。 1：工信部备案网站的全称或简称。 2：App应用的全称或简称。 3：公众号或小程序的全称或简称。 4：电商平台店铺名的全称或简称。 5：商标名的全称或简称。 说明 签名来源为工信部备案网站的全称或简称时，请在申请说明中添加网站域名，加快审核速度。
            'Remark'     => $param['Remark'],   //短信签名申请说明。请在申请说明中详细描述您的业务使用场景，申请工信部备案网站的全称或简称请在此处填写域名，长度不超过200个字符。
            //			              'OutId' => config('constant.name_admin') . '_SmsSign_' . date('YmdHis') ,   //外部流水扩展字段
        ];
        $paramData = array_merge($paramData, $param['SignFileList']);
        return $this->getDeRes($paramData, 'post');
    }

    /**
     * 调用接口DeleteSmsSign删除短信签名。
     */
    public function DeleteSmsSign($param) {
        // 1.2. 业务API参数
        $paramData = [
            'Action'   => 'DeleteSmsSign',       //系统规定参数。取值：SendSms。
            'SignName' => $param['SignName'],   //短信签名名称:发送消息的头/前缀，如【汇邦检测】
        ];
        return $this->getDeRes($paramData);
    }


    /**
     * 调用接口QuerySmsSign查询短信签名申请状态。
     */
    public function QuerySmsSign($param) {
        // 1.2. 业务API参数
        $paramData = [
            'Action'   => 'QuerySmsSign',       //系统规定参数。取值：SendSms。
            'SignName' => $param['SignName'],   //短信签名名称:发送消息的头/前缀，如【汇邦检测】
        ];
        return $this->getDeRes($paramData);
    }

    private function getDeRes($paramData, $method = 'get') {
        $res = $this->getRes($paramData, $method);
        return json_decode($res);
    }

    private function getRes($paramData, $method = 'get') {
        //时区设置
        date_default_timezone_set("GMT");
        // 1.1. 系统参数
        $data1 = $this->commonData();
        //合并参数
        $data = array_merge($data1, $paramData);
        // 1.3. 去除签名关键字Key
        if(isset($data['Signature'])) {
            unset($data['Signature']);
        }
        // 1.4. 参数KEY排序,将参数Key按字典顺序排序
        ksort($data);
        $data['Signature'] = $this->getSign($data, $method);
        // 1.6. 发送短信
        if($method === 'get') {
            $url = $this->_sendUrl.http_build_query($data);
            return curl($url);
        }
        $url1 = $this->_sendUrl;
        $res = curl($url1, $data, ['content-type: multipart/form-data']);
        return $res;
    }

    private function getSign($data, $method) {
        // 1.5. 构造待签名的字符串,生成规范化请求字符串
        $signString = '';
        foreach($data as $key => $value) {
            $signString .= '&'.urlencode($key).'='.urlencode($value);
        }
        // 生成用于计算签名的字符串 stringToSign
        $stringToSign = strtoupper($method).'&%2F&'.rawurlencode(substr($signString, 1));
        // 计算签名，注意accessKeySecret后面要加上字符'&'
        return base64_encode(hash_hmac('sha1', $stringToSign, $this->_secret.'&', true));
    }

    private function commonData() {
        return [
            'SignatureMethod'  => 'HMAC-SHA1',    //加密算法
            'SignatureNonce'   => mt_rand().'dfvn'.time().'fdfas',    //随机字符串
            'AccessKeyId'      => $this->_key,         //主账号AccessKey的ID。
            'SignatureVersion' => '1.0',          //版本
            'Timestamp'        => date('Y-m-d').'T'.date('H:i:s').'Z',          //发送时间
            'Format'           => 'json',          //返回数据格式
            'Version'          => '2017-05-25',      //版本
            'RegionId'         => 'cn-hangzhou',    //不知道是做什么的，如果你知道请注释下
        ];
    }

}
